#ifndef _CONFIG_H
#define _CONFIG_H


#include <assert.h>

#include <time.h>
#include <sys/time.h>    //gettimeofday 
#include <sys/stat.h>    //定义在打开和创建文件时用到的一些符号常量
#include <unistd.h>      // linux  read  write
#include <string.h>
#include <stdio.h>       // linux input output 
#include <stdlib.h>      //standard library 
#include <stdint.h>
#include <signal.h>      
#include <math.h>
#include <malloc.h>
#include <fcntl.h>       //定义 open,fcntl函数原型
#include <error.h>  

#include <sys/types.h>    //off_t
#include <sys/socket.h>   //socket ,blind ,listen ,accept,...
#include <netinet/in.h>   //sockaddr_in ,struct sockaddr,...
#include <arpa/inet.h>    //inet_addr ,inet_ntoa ,htonl,...
#include <net/if.h>       // struct ifreq ,struct ifconf
#include <sys/ioctl.h>    //setsockopt
#include <pthread.h>      //pthread_create
#include <netinet/tcp.h>  //
#include <sys/resource.h> 

#include <netdb.h>
#include <sys/epoll.h>

#define K 2
#define R 1
#define PORT 48000
#define BLK_SIZE 4*1024 //4KB
#define NODE_CONFIG "node_config"
#define DATANODE_NUM 6
#define CLIENT_NUM 1
#define COMMENTS '#'
#define ETH "eth"
#define IPLen 16
#define BUFFER_SIZE 8*1024
#define TIMEOUT_IN_MS 10000
#define Max_Wait 32
#define MSR_TRACE "trace.csv"
#define YCSB_TRACE "ycsb20k-0.8.csv"
#define STRIPE_NUM 300000
#define DUMMY_BLK_SIZE 1024*1024
#define CHECK_SUM 123
#define isYCSB 0
#define RECOVERY_ID 3
#define RECOVERY_NUM 100
#define IS_RECOVERY 1

typedef struct DataNode
{
	int nodeID;
	char tcp_ip[IPLen];
	char rdma_ip[IPLen];	
}DataNode;

typedef struct Connection
{
	int type;//0=client;1=datanode_server;2=datanode_client
	struct rdma_cm_id *id;
	struct ibv_qp *qp;
	void* conn_info;
	int len;
}Connection;

typedef struct Client_Connection
{
	struct ibv_mr *recv_mr;
  	struct ibv_mr *send_mr;

	char *recv_region;
	char *send_region;
}Client_Connection; 


typedef struct Context {
  struct ibv_context *ctx;
  struct ibv_pd *pd;
  struct ibv_cq *cq;
  struct ibv_comp_channel *comp_channel;

  pthread_t cq_poller_thread;
}Context;

typedef struct WriteRequest
{ 
	int type;//=1
  	long requestid;
	int srcid;
	int targetid;//请求发送的目标节点id
	int paritynodeid[R];//校验节点id
	int blockid;
	int parityid[R];
	char newdata[BLK_SIZE];
}WriteRequest;

typedef struct ReadRequest
{
	int type;//=0
	long requestid;
	int srcid;
	int targetid;
	int blockid;
}ReadRequest;

typedef struct WriteResponse
{
	int type;//=1
	long responseid;
	int res;//1=OK;0=ERR
}WriteResponse;

typedef struct ReadResponse
{
	int type;//=0
	long responseid;
	int res;//1=OK;0=ERR
	char newdata[BLK_SIZE];
}ReadResponse;

typedef struct UpdateContext
{
	long long id;
	int fd;
	int status;//init=R->0;
	int ready;//init=R->0
	WriteRequest* request;
}UpdateContext;


typedef struct UpdateEntity
{
	int type;//0=prepare,1=commit
	long long id;
	int blockid;
	int parityid;
	char newdata[BLK_SIZE];
	int checksum;
}UpdateEntity;

typedef struct UpdateCheck
{
	long long id;
	int res;//0=ERR,1=READY,2=OK
}UpdateCheck;

#endif
